// lib/omni_calendar_view.dart

import 'package:flutter/material.dart';
import 'src/controller/omni_calendar_controller.dart';
import 'src/ui/calendar_grid.dart';
import 'src/ui/calendar_header.dart';
import 'src/ui/weekday_row.dart';
import 'src/utils/localization_util.dart';

export 'src/controller/omni_calendar_controller.dart';

class OmniCalendarView extends StatefulWidget {
  /// 控制器，用于外部控制和状态查询
  final OmniCalendarController controller;

  /// 选择模式
  final SelectionType selectionType;

  /// 是否显示非本月的日期
  final bool showSurroundingDays;

  /// 是否显示农历 (仅在中文环境下有效)
  final bool showLunar;

  /// 语言环境
  final Locale locale;

  /// 顶部年月被点击时的回调
  final VoidCallback? onHeaderTap;

  /// 日期被单击时的回调
  final ValueChanged<DateTime>? onDateSelected;

  /// 日期范围被选择时的回调
  final ValueChanged<DateTimeRange>? onDateRangeSelected;

  /// 月份因滑动而改变时的回调
  final ValueChanged<DateTime>? onMonthChanged;

  const OmniCalendarView({
    super.key,
    this.selectionType = SelectionType.single,
    required this.controller,
    this.showSurroundingDays = true,
    this.showLunar = false,
    this.locale = const Locale('zh', 'CN'),
    this.onHeaderTap,
    this.onDateSelected,
    this.onDateRangeSelected,
    this.onMonthChanged,
  });

  @override
  State<OmniCalendarView> createState() => _OmniCalendarViewState();
}

class _OmniCalendarViewState extends State<OmniCalendarView> {
  late final PageController _pageController;
  static const int _initialPage = 6000; // 一个足够大的初始页面以支持双向滑动

  @override
  void initState() {
    super.initState();
    _pageController = PageController(initialPage: _calculateInitialPage());
    widget.controller.addListener(_onControllerUpdate);
    // 修复：将状态同步操作延迟到第一帧绘制之后
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (mounted) { // 确保 widget 仍然在树中
        // 将初始配置传入控制器
        widget.controller.toggleLunar(widget.showLunar);
        widget.controller.setSelectionType(widget.selectionType); // 同步选择模式
      }
    });
  }

  @override
  void didUpdateWidget(covariant OmniCalendarView oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.controller != oldWidget.controller) {
      oldWidget.controller.removeListener(_onControllerUpdate);
      widget.controller.addListener(_onControllerUpdate);
    }
    // 如果外部控件的showLunar属性改变，则更新控制器
    if (widget.showLunar != oldWidget.showLunar) {
      widget.controller.toggleLunar(widget.showLunar);
    }
    if (widget.selectionType != oldWidget.selectionType) {
      widget.controller.setSelectionType(widget.selectionType); // 同步选择模式
    }
    // 如果语言环境改变，只需重建即可
    if (widget.locale != oldWidget.locale) {
      setState(() {});
    }
  }

  @override
  void dispose() {
    widget.controller.removeListener(_onControllerUpdate);
    _pageController.dispose();
    super.dispose();
  }

  void _onControllerUpdate() {
    // 关键修复：在访问 page 属性前，检查 PageController 是否已经准备好。
    // hasClients 会在 PageController 附加到 PageView 后变为 true。
    if (!_pageController.hasClients) {
      // 如果控制器未准备好，我们可能仍然需要根据其他状态变化（如 showLunar）
      // 来重建UI，所以调用 setState()。
      setState(() {});
      return; // 提前返回，避免访问 .page 属性。
    }

    final displayedMonth = widget.controller.displayedDate;
    final currentPageMonth = _getDateForPage(_pageController.page!.round());

    if (displayedMonth.year != currentPageMonth.year ||
        displayedMonth.month != currentPageMonth.month) {
      final targetPage = _calculatePageForDate(displayedMonth);
      // 这里的 hasClients 检查是多余的了，因为上面已经检查过，但保留也无妨。
      if (_pageController.hasClients) {
        _pageController.jumpToPage(targetPage);
      }
    }

    // 控制器的notifyListeners会触发消费者的重建，
    // 但我们在这里调用setState以确保在需要时整个控件树都会重建。
    setState(() {});
  }

  int _calculateInitialPage() {
    return _calculatePageForDate(widget.controller.displayedDate);
  }

  int _calculatePageForDate(DateTime date) {
    final referenceDate = DateTime(1970, 1);
    final monthsDifference =
        (date.year - referenceDate.year) * 12 + date.month - referenceDate.month;
    return _initialPage + monthsDifference;
  }

  DateTime _getDateForPage(int page) {
    final referenceDate = DateTime(1970, 1);
    final monthsSinceReference = page - _initialPage;
    return DateTime(referenceDate.year,
        referenceDate.month + monthsSinceReference, 1);
  }

  /// 检查是否需要翻页，如果需要则执行动画
  void _handlePageTransition(DateTime targetDate) {
    // 仅当年月不同时才进行翻页
    if (targetDate.year != widget.controller.displayedDate.year ||
        targetDate.month != widget.controller.displayedDate.month) {
      // 需要延迟执行，以等待控制器状态更新完毕
      Future.delayed(const Duration(milliseconds: 50), () {
        if (!_pageController.hasClients) return;
        _pageController.animateToPage(
          _calculatePageForDate(targetDate),
          duration: const Duration(milliseconds: 400),
          curve: Curves.easeInOut,
        );
      });
    }
  }

  void _goToPreviousMonth() {
    // 检查 PageController 是否已附加到 PageView
    if (_pageController.hasClients) {
      _pageController.previousPage(
        duration: const Duration(milliseconds: 400),
        curve: Curves.easeInOut,
      );
    }
  }

  void _goToNextMonth() {
    if (_pageController.hasClients) {
      _pageController.nextPage(
        duration: const Duration(milliseconds: 400),
        curve: Curves.easeInOut,
      );
    }
  }


  @override
  Widget build(BuildContext context) {
    final localizations = OmniLocalizations(widget.locale);
    final isLunarVisible = widget.controller.showLunar && localizations.isChinese;

    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        CalendarHeader(
          controller: widget.controller,
          onHeaderTap: widget.onHeaderTap,
          locale: widget.locale,
          onPreviousMonthPressed: _goToPreviousMonth,
          onNextMonthPressed: _goToNextMonth,
        ),
        WeekdayRow(locale: widget.locale),
        LayoutBuilder(
          builder: (context, constraints) {
            // 动态计算高度
            final double cellAspectRatio = isLunarVisible ? 0.9 : 1;
            final double calendarHeight = (constraints.maxWidth / 7) * 6 / cellAspectRatio;
            return AnimatedContainer(
              duration: const Duration(milliseconds: 300),
              curve: Curves.easeInOut,
              height: calendarHeight,
              child: PageView.builder(
                controller: _pageController,
                onPageChanged: (page) {
                  final newMonth = _getDateForPage(page);
                  widget.controller.setDisplayedDate(newMonth);
                  widget.onMonthChanged?.call(newMonth);
                },
                itemBuilder: (context, index) {
                  final month = _getDateForPage(index);
                  return CalendarGrid(
                    month: month,
                    controller: widget.controller,
                    showSurroundingDays: widget.showSurroundingDays,
                    locale: widget.locale,
                    onDateSelected: (date) {
                      // 调用控制器更新状态
                      widget.controller.selectDate(date);

                      // 根据更新后的状态，触发对应的外部回调
                      if (widget.controller.selectionType == SelectionType.single) {
                        // 触发单选回调
                        if (widget.controller.selectedDate != null) {
                          widget.onDateSelected?.call(widget.controller.selectedDate!);
                        }
                      } else if (widget.controller.selectionType == SelectionType.range) {
                        // 触发范围选择回调
                        if (widget.controller.selectedDateRange != null) {
                          widget.onDateRangeSelected?.call(widget.controller.selectedDateRange!);
                        }
                      }

                      // 处理可能的翻页动画
                      _handlePageTransition(date);
                    },

                  );
                },
              ),
            );
          },
        ),
      ],
    );
  }
}
